#include "myUsart.h"

// 初始化
void USART1_Init(u32 bound)
{
    // 时钟使能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    // 初始化GPIO
    GPIO_InitTypeDef gpioInitDef;
    gpioInitDef.GPIO_Speed = GPIO_Speed_50MHz;
    // 数据输出
    gpioInitDef.GPIO_Pin = GPIO_Pin_9;
    // 复用推挽输出
    gpioInitDef.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &gpioInitDef);

    // 数据输入
    gpioInitDef.GPIO_Pin = GPIO_Pin_10;
    // 浮空输入
    gpioInitDef.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &gpioInitDef);

    // USART初始化
    USART_InitTypeDef usartInitDef;
    // 波特率
    usartInitDef.USART_BaudRate = bound;
    // 每一帧数据几个比特位
    usartInitDef.USART_WordLength = USART_WordLength_8b;
    // 停止位长度
    usartInitDef.USART_StopBits = USART_StopBits_1;
    // 奇偶校验
    usartInitDef.USART_Parity = USART_Parity_No;
    // 硬件流控制
    usartInitDef.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    // 模式 --> 收发模式
    usartInitDef.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &usartInitDef);

    // 开启USART
    USART_Cmd(USART1, ENABLE);

    // 清除发送中断状态
    USART_ClearFlag(USART1, USART_FLAG_TC);
    
    // 开启USART中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    // NVIC初始化
    NVIC_InitTypeDef nvicInitDef;
    // 中断通道
    nvicInitDef.NVIC_IRQChannel = USART1_IRQn;
    // 抢占式优先级
    nvicInitDef.NVIC_IRQChannelPreemptionPriority = 2;
    // 副优先级
    nvicInitDef.NVIC_IRQChannelSubPriority = 3;
    // 开启中断
    nvicInitDef.NVIC_IRQChannelCmd = ENABLE;
    // 应用
    NVIC_Init(&nvicInitDef);
}

// 缓冲数组存放接收的数据
u8 USART1_RX_BUF[USART1_REC_LEN]; 
// 接收状态
u16 USART1_RX_STA=0;  

// 中断函数
void USART1_IRQHandler(void)
{
    u8 res;
    // 判断是否有消息来
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        // 接收消息
        res = USART_ReceiveData(USART1);

        // 判断数据是否接收完毕
        if((USART1_RX_STA & 0x8000) != 1)
        {
            // 继续接收数据
            // 判断是否接收到 /r
            if(USART1_RX_STA & 0x4000)
            {
                // 接收到/r判断当前数据是不是/n
                // 是：表示数据接收完毕改变标志位
                // 不是：接收错误重新接收
                if(res == 0x0a) USART1_RX_STA |= 0x8000;
                else USART1_RX_STA = 0;
            }else
            {
                // 还没有接收到/r
                // 判断当前数据是不是/r --> 是改变标志位 --> 不是继续读取数据
                if(res == 0x0d) USART1_RX_STA |= 0x4000;
                else
                {
                    // 把当前数据存放到数组
                    USART1_RX_BUF[USART1_RX_STA & 0x3fff] = res;
                    // 状态位++
                    USART1_RX_STA ++;
                    //接收数据错误,重新开始接收
                    if(USART1_RX_STA > (USART1_REC_LEN - 1)) USART1_RX_STA = 0;	 
                }
            }
        }
 
        // 接收完消息并转发给发送者
        USART_SendData(USART1, res);
    }
}